package com.cn.algorithm.leetcode.array.two;

/*
*
*12. 整数转罗马数字
中等
相关标签
相关企业
七个不同的符号代表罗马数字，其值如下：

符号	值
I	1
V	5
X	10
L	50
C	100
D	500
M	1000
罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则：

如果该值不是以 4 或 9 开头，请选择可以从输入中减去的最大值的符号，将该符号附加到结果，减去其值，然后将其余部分转换为罗马数字。
如果该值以 4 或 9 开头，使用 减法形式，表示从以下符号中减去一个符号，例如 4 是 5 (V) 减 1 (I): IV ，9 是 10 (X) 减 1 (I)：IX。仅使用以下减法形式：4 (IV)，9 (IX)，40 (XL)，90 (XC)，400 (CD) 和 900 (CM)。
只有 10 的次方（I, X, C, M）最多可以连续附加 3 次以代表 10 的倍数。你不能多次附加 5 (V)，50 (L) 或 500 (D)。如果需要将符号附加4次，请使用 减法形式。
给定一个整数，将其转换为罗马数字。



示例 1：

输入：num = 3749

输出： "MMMDCCXLIX"

解释：

3000 = MMM 由于 1000 (M) + 1000 (M) + 1000 (M)
 700 = DCC 由于 500 (D) + 100 (C) + 100 (C)
  40 = XL 由于 50 (L) 减 10 (X)
   9 = IX 由于 10 (X) 减 1 (I)
注意：49 不是 50 (L) 减 1 (I) 因为转换是基于小数位
示例 2：

输入：num = 58

输出："LVIII"

解释：

50 = L
 8 = VIII
示例 3：

输入：num = 1994

输出："MCMXCIV"

解释：

1000 = M
 900 = CM
  90 = XC
   4 = IV
*
* */

import java.util.HashMap;
import java.util.Map;

public class IntegerToRoman {

    public static void main(String[] args) {
        System.out.println(intToRoman3(401));
    }

    /*
    *
    * if else直接写死
    *
    * */
    public static String intToRoman1(int num) {
        StringBuffer res = new StringBuffer();
        while (num > 0) {
            if (num >= 1000) {
                num -= 1000;
                res.append("M");
            } else if (num >= 900) {
                num -= 900;
                res.append("CM");
            } else if (num >= 500) {
                num -= 500;
                res.append("D");
            } else if (num >= 400) {
                num -= 400;
                res.append("CD");
            } else if (num >= 100) {
                num -= 100;
                res.append("C");
            } else if (num >= 90) {
                num -= 90;
                res.append("XC");
            } else if (num >= 50) {
                num -= 50;
                res.append("L");
            }else if (num >= 40) {
                num -= 40;
                res.append("XL");
            }else if (num >= 10) {
                num -= 10;
                res.append("X");
            }else if (num == 9) {
                num -= 9;
                res.append("IX");
            }else if (num >= 5) {
                num -= 5;
                res.append("V");
            }else if (num == 4) {
                num -= 4;
                res.append("IV");
            } else {
                num -= 1;
                res.append("I");
            }
        }
        return res.toString();
    }

    /*
    *
    * 传统写法：从头高位到低位依次判断；性能差
    *
    * */
    public static String intToRoman2(int num) {
        int length = 1;
        while (length * 10 <= num) {
            length *= 10;

        }
        Map<Integer, Character> map = new HashMap<>();
        map.put(1, 'I');
        map.put(5, 'V');
        map.put(10, 'X');
        map.put(50, 'L');
        map.put(100, 'C');
        map.put(500, 'D');
        map.put(1000, 'M');
        StringBuffer res = new StringBuffer();
        for (int i = length; i > 0; i /= 10) {
            int current = num / i;
            int value = current * i;
            num -= value;
            if (map.get(value) != null) {
                res.append(map.get(value));
                continue;
            }
            if (current != 4 && current != 9) {//当前位数是否是4或9
                if (value >= i * 5) {//是否大于5
                    res.append(map.get(i * 5));
                    value -= (i * 5);
                }
                while (value > 0) {
                    res.append(map.get(i));
                    value -= i;
                }
            } else {
                //next 即100， 500， 1000
                int next = value + i;
                res.append(map.get(next - value));
                res.append(map.get(next));
            }
        }
        return res.toString();
    }


    public static String intToRoman3(int num) {
        StringBuffer sb = new StringBuffer();
        int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        String[] symbols = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        for (int i = 0; i < values.length; i++) {
            int value = values[i];
            while (num >= value) {
                num -= value;
                sb.append(symbols[i]);
            }
        }
        return sb.toString();
    }
}
